<?php
/**
 * Created by PhpStorm.
 * @User: 王崇全
 * @Date: 2018/10/31 14:07
 */

namespace app\common\model;


use com\Hash;
use think\Db;

/**
 * Class 用户
 * @author  王崇全
 * @date    2018/10/31 14:07
 * @package app\common\model
 */
class User
{
    private const TAB_NAME      = 'user';
    private const TAB_USER_REAL = 'user_real';
    private const TAB_CAPITAL   = 'capital';

    /**
     * 添加用户
     * @author 王崇全
     * @date   2018/10/31 14:19
     * @param string $name  用户名
     * @param string $pwd   密码(加密后)
     * @param array  $other 其他信息 [
     *                      "nick_name"=>昵称,
     *                      "tel"=>电话,
     *                      "email"=>邮箱,
     *                      "profile_picture"=>头像,
     *                      "available"=>是否可用, //"yes"(默认)/"no"
     *                      ]
     * @return int 用户编号
     * @throws
     */
    public function add(string $name, string $pwd, array $other = [])
    : int {
        $pwdHash = Hash::pwd($pwd);

        try {
            $id = Db::name(self::TAB_NAME)
                    ->insert([
                        "name"            => $name,
                        "pwd"             => $pwdHash,
                        "nick_name"       => $other["nick_name"] ?? "",
                        "tel"             => $other["tel"] ?? "",
                        "email"           => $other["email"] ?? "",
                        "code"            => $other["code"] ?? "",
                        "admin_id"        => $other["admin_id"] ?? "",
                        "hierarchy_id"    => $other["hierarchy_id"] ?? "",
                        "profile_picture" => $other["profile_picture"] ?? "",
                        "available"       => (isset($other["available"]) && $other["available"] == "no") ? "no" : "yes",
                        "create_time"     => date("Y-m-d H:i:s"),
                    ], false, true);
        } catch (\Exception $e) {
            throw new \Exception('用户新增失败');
        }

        return $id;
    }

    /**
     * 编辑用户信息
     * @author 王崇全
     * @date   2018/10/31 14:52
     * @param int   $id
     * @param array $data 修改项 [
     *                    "name"=>用户名,
     *                    "pwd"=>密码,
     *                    "nick_name"=>昵称,
     *                    "tel"=>电话,
     *                    "email"=>邮箱,
     *                    "profile_picture"=>头像,
     *                    ]
     * @return bool
     * @throws
     */
    public function edit(int $id, array $data)
    : bool {

        $update = [];
        if (isset($data["name"])) {
            $update["name"] = $data["name"];
        }
        if (isset($data["pwd"])) {
            $update["pwd"] = Hash::pwd($data["pwd"]);
        }
        if (isset($data["nick_name"])) {
            $update["nick_name"] = $data["nick_name"];
        }
        if (isset($data["tel"])) {
            $update["tel"] = $data["tel"];
        }
        if (isset($data["email"])) {
            $update["email"] = $data["email"];
        }
        if (isset($data["profile_picture"])) {
            $update["profile_picture"] = $data["profile_picture"];
        }

        try {
            return Db::name(self::TAB_NAME)
                     ->where("id", $id)
                     ->update($update) ? true : false;
        } catch (\Exception $e) {
            throw new \Exception("用户信息修改失败");
        }
    }

    /**
     * 用户信息
     * @author 王崇全
     * @date   2018/10/31 14:59
     * @param int $id 用户编号
     * @return array 用户信息 [
     *                "u.name"=>用户名,
     *                "u.pwd"=>密码,
     *                "u.nick_name"=>昵称,
     *                "u.tel"=>手机号,
     *                "u.email"=>邮箱,
     *                "u.profile_picture"=>头像,
     *                "u.available"=>是否可用(yes/no),
     *                "u.create_time"=>注册时间,
     *                "u.delete_time"=>删除时间,
     *                "u.admin_id"=>管理员ID,
     *                "c.balance"=>账户余额,
     *                "real_name"=>真实姓名,
     *                "ur.id_num"=>身份证号,
     *                "ur.status"=>审核状态（1，审核中；2，审核通过；3，审核未通过）,
     *                ]
     * @throws
     */
    public function info(int $id)
    : array {
        try {
            $info = Db::name(self::TAB_NAME)
                      ->alias('u')
                      ->field([
                          "u.name",
                          "u.pwd",
                          "u.nick_name",
                          "u.tel",
                          "u.email",
                          "u.profile_picture",
                          "u.available",
                          "u.create_time",
                          "u.delete_time",
                          "u.admin_id",
                          "c.balance",
                          "ur.name" => "real_name",
                          "ur.id_num",
                          "ur.status",
                      ])
                      ->join(self::TAB_CAPITAL.' c', 'u.id = c.user_id')
                      ->join(self::TAB_USER_REAL.' ur', 'u.id = ur.user_id', 'left')
                      ->where("u.id", $id)
                      ->whereNull("u.delete_time")
                      ->find();
            if (!$info) {
                return [];
            }

            $a     = new Admin();
            $admin = $a->getAdmin();

            $h         = new Hierarchy();
            $hierarchy = $h->getHierarchy();

            $info['admin_name']     = $admin[$info['admin_id']]['name'];
            $info['hierarchy_name'] = $hierarchy[$admin[$info['admin_id']]['hierarchy_id']];

        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return $info;
    }

    /**
     * 用户列表
     * @author 王崇全
     * @date   2018/10/31 13:58
     * @param int   $admin_id 管理员id
     * @param array $where    检索条件 [
     *                        "start_time"=>起始注册时间,
     *                        "end_time"=>截止注册时间,
     *                        "available"=>是否可用, // "yes"/"no"
     *                        "including_deleted"=>是否包括已删除了的, // "yes"/"no"
     *                        ]
     * @param int   $page     页码
     * @param int   $pageSize 页幅
     * @return array [count=>总数,list=>[
     *                        "id"=>编号,
     *                        "name"=>用户名,
     *                        "nick_name"=>昵称,
     *                        "tel"=>电话,
     *                        "email"=>邮箱,
     *                        "profile_picture"=>头像,
     *                        "available"=>是否可用,
     *                        "create_time"=>注册时间,
     *                        ]]
     * @throws
     */
    public function list(int $admin_id, array $where, int $page, int $pageSize)
    : array {

        $db = Db::name(self::TAB_NAME);

        $db->alias('u')
           ->join(self::TAB_CAPITAL.' c', 'u.id = c.user_id', 'left')
           ->join(self::TAB_USER_REAL.' ur', 'u.id = ur.user_id', 'left');

        if (isset($where["start_time"])) {
            $db->where("u.create_time", ">= TIME", $where["start_time"]);
        }
        if (isset($where["end_time"])) {
            $db->where("u.create_time", "<= TIME", $where["end_time"]);
        }
        if (isset($where["available"])) {
            $db->where("u.available", $where["available"]);
        }
        if (isset($where['name'])) {
            $db->where("u.name|u.tel", $where["name"]);
        }
        if (isset($where['real_status'])) {
            $db->where("ur.status", $where["real_status"]);
        }

        $db->whereNull('u.delete_time');

        $a   = new Admin();
        $ids = $a->getIds($admin_id);

        if (isset($where['agent_name'])) {

            $agent = $a->getAdminByName($where['agent_name']);
            if ($agent) {
                $agent_id = $agent['id'];
                if (!in_array($agent_id, $ids)) {
                    $ids = 0;
                } else {
                    $ids = $a->getIds($agent_id);
                }
            } else {
                $ids = 0;
            }
        }

        $db->where('u.admin_id', 'in', $ids);

        //查询总数
        $count = $db->count("u.id");
        if ($count < 1) {
            return [
                "count" => 0,
                "list"  => [],
            ];
        }

        try {
            //列表
            $list = $db->field([
                "u.id",
                "u.name",
                "u.nick_name",
                "u.tel",
                "u.email",
                "u.profile_picture",
                "u.available",
                "u.create_time",
                "u.admin_id",
                "c.balance",
                "ur.name",
                "ur.id_num",
                "ur.status",
            ])
                       ->order(["u.id" => "DESC"])
                       ->page($page, $pageSize)
                       ->select();

            $a         = new Admin();
            $admin     = $a->getAdmin();
            $h         = new Hierarchy();
            $hierarchy = $h->getHierarchy();

            foreach ($list as $key => $val) {
                $list[$key]['admin_name']     = $admin[$val['admin_id']]['name'];
                $list[$key]['hierarchy_name'] = $hierarchy[$admin[$val['admin_id']]['hierarchy_id']];
            }
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return [
            "count" => $count,
            "list"  => $list,
        ];
    }

    /**
     * 删除用户-软删除
     * @author 王崇全
     * @date   2018/10/31 15:28
     * @param array $ids 编号集合
     * @return void
     * @throws
     */
    public function delete(array $ids)
    : void {

        try {
            Db::name(self::TAB_NAME)
              ->where("id", "in", $ids)
              ->setField("delete_time", date("Y-m-d H:i:s"));
        } catch (\Exception $e) {
            throw new \Exception("用户删除失败");
        }
    }

    /**
     * 禁用用户
     * @author 王崇全
     * @date
     * @param array $ids 编号集合
     * @return bool
     * @throws \Exception
     */
    public function disable(array $ids)
    : bool {

        try {
            return Db::name(self::TAB_NAME)
                     ->where("id", "in", $ids)
                     ->setField("available", "no") ? true : false;
        } catch (\Exception $e) {
            throw new \Exception("用户禁用失败");
        }
    }

    /**
     * 检查是否存在
     * @author 王崇全
     * @date   2018/10/31 15:46
     * @param int    $type  1,检查用户名;2,检查电话;3,检查邮箱
     * @param string $value 要检查的值
     * @return bool 是否已存在
     * @throws
     */
    public function checkExits(int $type, string $value)
    : bool {

        if ($type === 1) {
            $field = "name";
        } elseif ($type === 2) {
            $field = "tel";
        } elseif ($type === 3) {
            $field = "email";
        } else {
            throw new \Exception("要检查的类型错误");
        }

        return Db::name(self::TAB_NAME)
                 ->field("id")
                 ->where($field, $value)
                 ->find() ? true : false;
    }

    /**
     * 验证用户名和密码是否匹配
     * @author 王崇全
     * @date   2018/10/31 15:56
     * @param string $name
     * @param string $pwd
     * @return bool
     * @throws
     */
    public function checkPwd(string $name, string $pwd)
    {
        try {
            $res = Db::name(self::TAB_NAME)
                     ->whereOr([
                         'name'  => $name,
                         'email' => $name,
                         'tel'   => $name,
                     ])
                     ->whereNull('delete_time')
                     ->value("pwd");

        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return $res === Hash::pwd($pwd);
    }

    /**
     * 验证用户名和密码是否匹配
     * @author 王崇全
     * @date   2018/10/31 15:56
     * @param string $id
     * @param string $pwd
     * @return bool
     * @throws
     */
    public function checkPwdById(string $id, string $pwd)
    {
        try {
            $res = Db::name(self::TAB_NAME)
                     ->where([
                         'id' => $id,
                     ])
                     ->whereNull('delete_time')
                     ->value("pwd");

        } catch (\Exception $e) {
            throw new \Exception("密码查询失败");
        }

        return $res === Hash::pwd($pwd);
    }

    /**
     * 获取用户信息
     * @author 王崇全
     * @date   2018/10/31 15:56
     * @param string $name
     * @return array
     * @throws
     */
    public function getInfo(string $name)
    {
        try {
            $res = Db::name(self::TAB_NAME)
                     ->field([
                         "id",
                         "hierarchy_id",
                         "name",
                         "nick_name",
                         "tel",
                         "email",
                         "code",
                         "admin_id",
                         "profile_picture",
                         "available",
                         "create_time",
                         "delete_time",
                     ])
                     ->whereOr([
                         'name'  => $name,
                         'email' => $name,
                         'tel'   => $name,
                     ])
                     ->find();

        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return $res;
    }

    /**
     * 查询手机号或者邮箱是否存在
     * @author 王海东
     * @date
     * @param string $name
     * @return bool
     * @throws \Exception
     */
    public function checkUsername(string $name)
    : bool {
        try {
            $res = Db::name(self::TAB_NAME)
                     ->whereOr([
                         'email' => $name,
                         'tel'   => $name,
                     ])
                     ->whereNull('delete_time')
                     ->value("id");
        } catch (\Exception $e) {
            throw new \Exception('查询失败');
        }

        return $res ? true : false;
    }


    /**
     * 根据邀请码获取用户信息
     * @author 王海东
     * @date
     * @param string $code 用户邀请码
     * @return array
     * @throws \Exception
     */
    public function getUserByCode(string $code)
    : array {
        try {
            $data = Db::name(self::TAB_NAME)
                      ->field('hierarchy_id,admin_id')
                      ->where('code', $code)
                      ->whereNull('delete_time')
                      ->find() ?? [];

            return $data;
        } catch (\Exception $e) {
            throw new \Exception('查询失败');
        }
    }

    /**
     * 根据管理员获取相关用户总数
     * @author 王海东
     * @date
     * @param int $admin_id
     * @return float|string
     */
    public function getCountByAdmin(int $admin_id)
    {
        $count = Db::name(self::TAB_NAME)
                   ->where('admin_id', $admin_id)
                   ->count();

        return $count;
    }
}